home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / usenet / sources / volume91 / utilitys / amyinfo1 / part01 / AmyInfo.c next >
C/C++ Source or Header  |  1991-07-08  |  15KB  |  649 lines

  1.  
  2. /*    AmyInfo v1.3 by Digital Design, Inc.
  3.  
  4.     Author: Juha Tuominen
  5.     Released: 30-Jun-91        */
  6.  
  7. #include <exec/types.h>
  8. #include <exec/memory.h>
  9. #include <exec/execbase.h>
  10. #include <exec/tasks.h>
  11. #include <libraries/dos.h>
  12. #include <devices/timer.h>
  13. #include <intuition/intuitionbase.h>
  14. #include <graphics/rastport.h>
  15. #include <graphics/gfx.h>
  16. #include <graphics/gfxmacros.h>
  17. #include <graphics/text.h>
  18. #include <proto/all.h>
  19. #include <string.h>
  20. #include <stdio.h>
  21. #include <stdlib.h>
  22.  
  23. #define FONTSIZE 8
  24. #define NAME "AmyInfo"
  25. #define STACK_SIZE 1000L    /* Meisseli-Make's stack size */
  26.  
  27. BOOL    task_added=FALSE;
  28. BOOL    timeropen=FALSE;
  29. BOOL    keepgoing=TRUE;
  30. BOOL    time_requested=FALSE;
  31. BOOL    log=FALSE;
  32. BOOL    init=TRUE;
  33. char    *months[]={"","Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};
  34. char    date[16]="               ";
  35. char    tempdays[8]="       ";
  36. char    timetemp[8]="       ";
  37. char    booted[80];
  38. int        upsecs=0,upmins=0,uphours=0,updays=0;
  39. ULONG    maxchip, maxfast, freechip=0, freefast=0;
  40. ULONG    cputime=NULL,cputemp=NULL,prevcpu=68;
  41. ULONG    count=0;
  42. ULONG    chipscale=0, fastscale=0;
  43. ULONG    jakaja=0,cputemp2=0;
  44. char    *taskname="Meisseli-Make";
  45. APTR    stack=NULL;
  46. USHORT    ditherdata=0x5555;
  47. int        tempmins,cpuload=0;
  48.  
  49. extern    struct ExecBase    *SysBase;
  50. struct    IntuitionBase *IntuitionBase=NULL;
  51. struct    Window *window=NULL;
  52. struct    GfxBase *GfxBase=NULL;
  53. struct    MsgPort *timerport=NULL;
  54. struct    timerequest *timermsg=NULL;
  55. struct    IntuiText abouttext[];
  56. struct    IntuiText proceed;
  57. struct    Task *task=NULL;
  58. struct    NewWindow mywindow = 
  59. {
  60.     100,
  61.     100,
  62.     400,
  63.     76,
  64.     0,1,
  65.     CLOSEWINDOW | MOUSEBUTTONS,
  66.     SMART_REFRESH | WINDOWDRAG | WINDOWCLOSE | WINDOWDEPTH | RMBTRAP,
  67.     NULL,
  68.     NULL,
  69.     NAME,
  70.     NULL,
  71.     NULL,
  72.     NULL,
  73.     NULL,
  74.     NULL,
  75.     NULL,
  76.     WBENCHSCREEN
  77.  
  78. };
  79.  
  80. struct TextAttr aifont[1] =
  81. {
  82.     {(UBYTE *)"topaz.font",8,FS_NORMAL ,FPF_ROMFONT},
  83. };
  84.  
  85. struct IntuiText abouttext[7] =
  86. {
  87.     {2,1,JAM1,8, 4,(struct TextAttr *)&aifont[0],(UBYTE *)"AmyInfo v1.3",(struct IntuiText *)&abouttext[1]},
  88.     {2,1,JAM1,8,14,(struct TextAttr *)&aifont[0],(UBYTE *)"by Juha Tuominen",(struct IntuiText *)&abouttext[2]},
  89.     {2,1,JAM1,8,22,(struct TextAttr *)&aifont[0],(UBYTE *)"Copyright (c) 1991",(struct IntuiText *)&abouttext[3]},
  90.     {2,1,JAM1,8,30,(struct TextAttr *)&aifont[0],(UBYTE *)"Digital Design, Inc.",(struct IntuiText *)&abouttext[4]},
  91.     {2,1,JAM1,8,38,(struct TextAttr *)&aifont[0],(UBYTE *)" ",(struct IntuiText *)&abouttext[5]},
  92.     {2,1,JAM1,8,46,(struct TextAttr *)&aifont[0],(UBYTE *)"Meisseli-Make has found",(struct IntuiText *)&abouttext[6]},
  93.     {2,1,JAM1,8,54,(struct TextAttr *)&aifont[0],(UBYTE *)"0 perfect numbers.",(struct IntuiText *)NULL}
  94. };
  95.  
  96. struct IntuiText proceed =
  97. {
  98.     2,1,JAM1,5,3,(struct TextAttr *)&aifont[0],(UBYTE *)"Continue",(struct IntuiText *)NULL
  99. };
  100.  
  101.  
  102.  
  103. void cleanexit(int error);
  104. void openthings(void);
  105. void copyfile(char *source, char *dest);
  106. void addtimerequest(long secs, long micros);
  107. void currenttime(void);
  108. void changefont(void);
  109. void initgraphics(void);
  110. void printfinetext(char *text,int x,int y,int color);
  111. ULONG maxmemsize(long memtype);
  112. void idletask(void);
  113. void __saveds switchroutine(void);
  114.  
  115. void CXBRK(void) 
  116.     cleanexit(0);
  117. }
  118.  
  119. void cleanexit(int error)
  120. {
  121.     if(task_added) RemTask(task);
  122.     if(task) FreeMem(task,sizeof(struct Task));
  123.     if(stack) FreeMem(stack,STACK_SIZE);
  124.     if(timeropen)
  125.     {
  126.         if(time_requested)
  127.         {
  128.             AbortIO((struct IORequest *)timermsg);
  129.             WaitIO((struct IORequest *)timermsg);
  130.         }
  131.         CloseDevice((struct IORequest *)timermsg);
  132.     }
  133.     if(timermsg) DeleteExtIO((struct IORequest *)timermsg);
  134.     if(timerport) DeletePort(timerport);
  135.     if(window) CloseWindow(window);
  136.     if(GfxBase) CloseLibrary(GfxBase);
  137.     if(IntuitionBase) CloseLibrary((struct Library *)IntuitionBase);
  138.     exit(error);
  139. }
  140.  
  141.  
  142. void openthings(void)
  143. {
  144.     FILE    *fp;
  145.  
  146.     if(!DeviceProc("AmyInfo:") && log)
  147.     {
  148.         printf("\aAmyInfo: not assigned\n");
  149.         cleanexit(10);
  150.     }
  151.     if(!DeviceProc("T:") && log)
  152.     {
  153.         printf("\aT: not assigned\n");
  154.         cleanexit(10);
  155.     }
  156.     if (!(GfxBase=(struct GfxBase *)OpenLibrary("graphics.library",33L)))
  157.     {
  158.         printf("\aError opening GfxBase\n");
  159.         cleanexit(30);
  160.     }
  161.     if (!(IntuitionBase=(struct IntuitionBase*)OpenLibrary("intuition.library",33L)))
  162.     {
  163.         printf("\aError opening IntuitionBase\n");
  164.         cleanexit(30);
  165.     }
  166.     if(!(timerport=CreatePort(0,0)))
  167.     {
  168.         printf("\aError creating timerport\n");
  169.         cleanexit(22);
  170.     }
  171.     if(!(timermsg=(struct timerequest *) CreateExtIO(timerport, sizeof(struct timerequest))))
  172.     {
  173.         printf("\aError creating timerequest\n");
  174.         cleanexit(22);
  175.     }
  176.     if(OpenDevice("timer.device", UNIT_VBLANK, ((struct IORequest *) timermsg), 0))
  177.     {
  178.         printf("\aError opening timer.device\n");
  179.         cleanexit(22);
  180.     }
  181.     timeropen=TRUE;
  182.     if(!(window=OpenWindow(&mywindow)))
  183.     {
  184.         printf("\aError opening window\n");
  185.         cleanexit(27);
  186.     }
  187.     if(!(stack=AllocMem(STACK_SIZE, MEMF_CLEAR)))
  188.     {
  189.         printf("\aCannot allocate stack for idletask\n");
  190.         cleanexit(10);
  191.     }
  192.     if(!(task=(struct Task*)AllocMem(sizeof(struct Task),MEMF_CLEAR|MEMF_PUBLIC)))
  193.     {
  194.         printf("\aCannot create idletask\n");
  195.         cleanexit(10);
  196.     }
  197.  
  198.     maxchip=maxmemsize(MEMF_CHIP);
  199.     maxfast=maxmemsize(MEMF_FAST);
  200.  
  201.     /*    Because we run this part only once we just have to assume that user 
  202.         does not add memory cartiges while this program is running :) */
  203.  
  204.     chipscale=maxchip/142;
  205.     fastscale=maxfast/142;
  206.     changefont();
  207.     if(log)
  208.     {
  209.         currenttime();
  210.         if(!(fp=fopen("AmyInfo:SystemLog","a")))
  211.         {
  212.             printf("\aUnable to open AmyInfo:SystemLog - check for protect bits!\n");
  213.             cleanexit(10);
  214.         }
  215.         fputs(booted,fp);
  216.         fclose(fp);
  217.         copyfile("AmyInfo:SystemLog","T:TEMP.AmyInfo");
  218.     }
  219.  
  220. }
  221.  
  222. void copyfile(char *source, char *dest)
  223. {
  224.     FILE    *fpsource,*fpdest;
  225.     char    store[80]="AmyInfo!";
  226.     
  227.     if(!(fpsource=fopen(source,"r")))
  228.         cleanexit(10);
  229.     else
  230.     {
  231.         if(!(fpdest=fopen(dest,"w")))
  232.             cleanexit(10);
  233.         else
  234.         {
  235.             while(store[0]!=NULL)
  236.             {
  237.                 fgets(store,80,fpsource);
  238.                 fputs(store,fpdest);
  239.             }
  240.             fclose(fpdest);
  241.         }
  242.         fclose(fpsource);
  243.     }
  244. }
  245.  
  246. void addtimerequest(long secs, long micros)
  247. {
  248.     time_requested=TRUE;
  249.     timermsg->tr_node.io_Command=TR_ADDREQUEST;
  250.     timermsg->tr_time.tv_secs=secs;
  251.     timermsg->tr_time.tv_micro=micros;
  252.     SendIO((struct IORequest *)timermsg);
  253. }
  254.  
  255.  
  256. void currenttime(void)
  257. {
  258.     long    n;
  259.     int        m,d,y,hours,mins,secs;
  260.     char    temp[16],uptemp[40];
  261.     long    v[3];
  262.     struct    DateStamp ds;
  263.     FILE    *fp;
  264.  
  265.     DateStamp((struct DateStamp *)v);
  266.     n=v[0]-2251;
  267.     y=(4*n+3)/1461;
  268.     n-=1461*(long)y/4;
  269.     y+=84;
  270.     m=(5*n+2)/153;
  271.     d=n-(153*m+2)/5+1;
  272.     m+=3;
  273.     if (m>12)
  274.     {
  275.         y++;
  276.         m-=12;
  277.     }
  278.  
  279. /*    Date stamp conversation routine from Robert A. Peck's book 
  280.     'Programming Guide to the Amiga. Routine by Tom Rokicki. */
  281.  
  282.     sprintf(temp,"%02d-%3s-%02d",d,months[m],y);
  283.     if(strcmp(temp,date))
  284.     {
  285.         printfinetext(temp,70,38,2);
  286.         strcpy(date,temp);
  287.     }
  288.  
  289.     DateStamp(&ds);
  290.     hours=ds.ds_Minute/60;
  291.     mins=ds.ds_Minute%60;
  292.     secs=ds.ds_Tick/50;    
  293.  
  294.     sprintf(temp,"%02d:%02d:%02d",hours,mins,secs);
  295.     if(strcmp(timetemp,temp))
  296.     {
  297.         strcpy(timetemp,temp);
  298.         printfinetext(temp,70,25,2);
  299.         if(++upsecs>59)
  300.         {
  301.             upsecs=0;
  302.             if(++upmins>59)
  303.             {
  304.                 upmins=0;
  305.                 if(++uphours>23)
  306.                 {
  307.                     uphours=0;
  308.                     updays++;
  309.                 }
  310.             }
  311.         }        
  312.         if(init)
  313.         {
  314.             sprintf(booted,"\nBooted: %s  %s\n",date,temp);
  315.             tempmins=mins;
  316.             init=FALSE;
  317.         }
  318.         sprintf(uptemp,"%02d:%02d:%02d",uphours,upmins,upsecs);
  319.         printfinetext(uptemp,230,25,2);
  320.     }
  321.  
  322.     sprintf(temp,"%04d",updays); /* I think 9999 days is enough for most of people :) */
  323.     if(strcmp(temp,tempdays))
  324.     {
  325.         printfinetext(temp,230,38,2);
  326.         strcpy(tempdays,temp);
  327.     }
  328.     if(tempmins-mins==45 || mins-tempmins==15)
  329.     {
  330.         tempmins=mins;
  331.         copyfile("T:TEMP.AmyInfo","AmyInfo:SystemLog");
  332.         if(!(fp=fopen("AmyInfo:SystemLog","a")))
  333.             cleanexit(10);
  334.         else
  335.         {
  336.             sprintf(booted,"Uptime: %s %s    Average CPU load: %d %%\n",temp,uptemp,100-cpuload);
  337.             fputs(booted,fp);
  338.             fclose(fp);
  339.         }
  340.     }
  341. }
  342.  
  343. void changefont(void)
  344. {
  345.     struct    TextAttr    textattr;
  346.     struct    TextFont    *textfont;
  347.  
  348.     textattr.ta_Name="topaz.font";
  349.     textattr.ta_YSize=FONTSIZE;
  350.     textattr.ta_Style=FS_NORMAL;
  351.     textattr.ta_Flags=FPF_DESIGNED | FPF_ROMFONT;
  352.  
  353.     if(textfont=OpenFont(&textattr))
  354.         SetFont(window->RPort,textfont);
  355.     else
  356.     {
  357.         printf("Cannot open topaz 8!\n");
  358.         cleanexit(10);
  359.     }
  360. }
  361.  
  362. void initgraphics(void)
  363. {
  364.     printfinetext("Time:",10,25,3);
  365.     printfinetext("Date:",10,38,3);
  366.     printfinetext("UpTime:",160,25,3);
  367.     printfinetext("Days:",160,38,3);
  368.     printfinetext("Chip:         K",10,51,3);
  369.     printfinetext("Fast:          K",160,51,3);
  370.  
  371.     SetDrMd(window->RPort,JAM1);
  372.     SetAPen(window->RPort,1);
  373.     Move(window->RPort,310,69);
  374.     Draw(window->RPort,310,18);
  375.     Draw(window->RPort,390,18);
  376.     Move(window->RPort,7,69);
  377.     Draw(window->RPort,7,59);
  378.     Draw(window->RPort,148,59);
  379.     Move(window->RPort,152,69);
  380.     Draw(window->RPort,152,59);
  381.     Draw(window->RPort,303,59);
  382.     SetAPen(window->RPort,2);
  383.     Draw(window->RPort,303,69);
  384.     Draw(window->RPort,153,69);
  385.     Move(window->RPort,148,60);
  386.     Draw(window->RPort,148,69);
  387.     Draw(window->RPort,8,69);
  388.     Move(window->RPort,390,19);
  389.     Draw(window->RPort,390,69);
  390.     Draw(window->RPort,310,69);    
  391. }
  392.  
  393.  
  394. ULONG maxmemsize(long memtype)
  395. {
  396.     ULONG blocksize=0;
  397.     struct MemHeader *MemHeader;
  398.  
  399.     Forbid();
  400.         for(MemHeader=(struct MemHeader *)SysBase->MemList.lh_Head;MemHeader->mh_Node.ln_Succ;MemHeader=(struct MemHeader *)MemHeader->mh_Node.ln_Succ)
  401.         {
  402.             if(MemHeader->mh_Attributes&memtype)
  403.                 blocksize+=((ULONG)MemHeader->mh_Upper-(ULONG)MemHeader->mh_Lower);
  404.         }
  405.     Permit();
  406.  
  407.     return(blocksize);
  408.  
  409.     /* MaxMemSize() by Louis A. Mamakos. */
  410. }
  411.  
  412.  
  413. void updatememorybar(void)
  414. {
  415.     ULONG currentchip, currentfast;
  416.     long tempx;
  417.     char temp[16];
  418.  
  419.     currentchip=AvailMem(MEMF_CHIP);
  420.     currentfast=AvailMem(MEMF_FAST);
  421.  
  422.  
  423.     if(currentchip!=freechip)
  424.     {
  425.         sprintf(temp,"%05d",currentchip/1024);
  426.         printfinetext(temp,70,51,2);
  427.  
  428.         tempx=currentchip/chipscale;
  429.         SetDrMd(window->RPort,JAM1);
  430.         if(freechip>currentchip)
  431.         {
  432.             SetAPen(window->RPort,0);
  433.             RectFill(window->RPort,tempx+10,61,freechip/chipscale+11,67);
  434.         }
  435.         SetAPen(window->RPort,3);
  436.         RectFill(window->RPort,10,62,tempx+10,66);
  437.         Move(window->RPort,tempx+11,61);
  438.         SetAPen(window->RPort,1);
  439.         Draw(window->RPort,tempx+11,67);
  440.         Draw(window->RPort,9,67);
  441.         SetAPen(window->RPort,2);
  442.         Draw(window->RPort,9,61);
  443.         Draw(window->RPort,tempx+11,61);
  444.         freechip=currentchip;                
  445.     }
  446.  
  447.     if(currentfast!=freefast)
  448.     {
  449.         sprintf(temp,"%05d",currentfast/1024);
  450.         printfinetext(temp,230,51,2);
  451.  
  452.         tempx=currentfast/fastscale;
  453.         SetDrMd(window->RPort,JAM1);
  454.         if(freefast>currentfast)
  455.         {
  456.             SetAPen(window->RPort,0);
  457.             RectFill(window->RPort,tempx+155,61,freefast/fastscale+156,67);
  458.         }
  459.         SetAPen(window->RPort,3);
  460.         RectFill(window->RPort,155,62,tempx+155,66);
  461.         Move(window->RPort,tempx+156,61);
  462.         SetAPen(window->RPort,1);
  463.         Draw(window->RPort,tempx+156,67);
  464.         Draw(window->RPort,154,67);
  465.         SetAPen(window->RPort,2);
  466.         Draw(window->RPort,154,61);
  467.         Draw(window->RPort,tempx+156,61);
  468.         freefast=currentfast;                
  469.     }
  470.     /* scale cputime to usable form - we've got 50 pixels to fill */
  471.     cputemp=(100*cputemp/60)/2;
  472.     ScrollRaster(window->RPort,1,0,311,19,389,68);
  473.     SetDrMd(window->RPort,JAM1);
  474.     SetAPen(window->RPort,3);
  475.     if(ditherdata==0x5555)
  476.         ditherdata=0xaaaa;
  477.     else
  478.         ditherdata=0x5555;
  479.     SetDrPt(window->RPort,ditherdata);
  480.     Move(window->RPort,389,68);
  481.     Draw(window->RPort,389,68-cputemp);
  482.     SetAPen(window->RPort,0);
  483.     Draw(window->RPort,389,19);
  484.     SetDrPt(window->RPort,~0);
  485.     SetAPen(window->RPort,1);
  486.     Move(window->RPort,388,prevcpu);
  487.     Draw(window->RPort,389,68-cputemp);
  488.     prevcpu=68-cputemp;
  489. }
  490.  
  491. void printfinetext(char *text,int x, int y, int color)
  492. {
  493.     int    tempy,
  494.         tempx,
  495.         len,
  496.         x1,
  497.         y1;
  498.     struct RastPort *rastport=window->RPort;
  499.  
  500.     SetDrMd(rastport,JAM2);
  501.     SetAPen(rastport,0);
  502.     SetBPen(rastport,0);
  503.     Move(rastport,x,y+2-FONTSIZE);
  504.     len=strlen(text);
  505.     tempy=y+2-FONTSIZE;
  506.     tempx=x+len*8;
  507.     x1=x+1;
  508.     y1=y+1;
  509.  
  510.     WaitTOF();
  511.  
  512.     /*     Uh, well .. I can't discover any better way to avoid the flickering.
  513.         Don't place AmyInfo too high on your WB-screen :)
  514.         It does not make any flickering on my big A, but I've got A2620..
  515.         The following part will take ~5-> lines to be executed */
  516.  
  517.     Draw(rastport,tempx,tempy);
  518.     SetAPen(rastport,1);
  519.     Move(rastport,x1,y1);
  520.     Text(rastport,text,len);
  521.     SetDrMd(rastport,JAM1);
  522.     SetAPen(rastport,color);
  523.     Move(rastport,x,y);
  524.     Text(rastport,text,len);
  525. }
  526.  
  527. void idletask(void)    /*    This is Meisseli-Make! */
  528. {
  529.     ULONG suurinluku=1,taydellinenluku,luku;
  530.  
  531.     Disable();
  532.         task->tc_Switch=switchroutine;
  533.         task->tc_Flags|=TF_SWITCH;
  534.     Enable();
  535.  
  536.     while(1)
  537.     {
  538.         taydellinenluku=0;
  539.         for(luku=suurinluku;luku>1;luku--)
  540.         {
  541.             if(!(suurinluku%luku))
  542.                 taydellinenluku+=luku;
  543.         }
  544.         if(taydellinenluku==suurinluku)
  545.             count++;
  546.         suurinluku++;
  547.     }
  548. }
  549.  
  550. void __saveds switchroutine(void)
  551. {
  552.     /*    Thanks to Juhani Vehvilainen for sweatting with me because of
  553.         this idle counting routine */
  554.  
  555.     cputime+=SysBase->Quantum-SysBase->Elapsed;
  556. }
  557.  
  558. void main(int argc, char *argv[])
  559. {
  560.     ULONG    timersignal, 
  561.             idcmpsignal, 
  562.             signals, 
  563.             class;
  564.     UWORD    code, 
  565.             qualifier;
  566.     struct    IntuiMessage *msg=NULL;
  567.     char    temp[80];
  568.     int        i;
  569.  
  570.     if(argc==2 && (!strncmp(argv[1],"?",1) || !strncmp(argv[1],"-?",2)))
  571.     {
  572.         printf("\nUsage: AmyInfo <LEFT> <TOP>\n");
  573.         printf("AmyInfo v1.3  Copyright (c) 1991 Juha Tuominen / Digital Design, Inc.\n\n");
  574.     }
  575.     else
  576.     {
  577.         if(argc>1)
  578.         {
  579.             for(i=1;i<=argc;i++)
  580.             {
  581.                 if(!strncmp(argv[i],"-log",4))
  582.                     log=TRUE;
  583.             }
  584.         }
  585.         if(argc>=3)
  586.         {
  587.             mywindow.LeftEdge=atoi(argv[1]);
  588.             mywindow.TopEdge=atoi(argv[2]);
  589.         }
  590.         
  591.         openthings();
  592.         initgraphics();
  593.  
  594.         timersignal = 1L << timerport->mp_SigBit;
  595.         idcmpsignal = 1L << window->UserPort->mp_SigBit;
  596.         addtimerequest(0,1);
  597.  
  598.         task->tc_Node.ln_Type=NT_TASK;
  599.         task->tc_Node.ln_Name=taskname;
  600.         task->tc_Node.ln_Pri=-128;
  601.         task->tc_SPLower=(APTR)stack;
  602.         task->tc_SPUpper=(APTR)(STACK_SIZE+(ULONG)stack);
  603.         task->tc_SPReg=task->tc_SPUpper;
  604.         AddTask(task,idletask,0L);
  605.         task_added=TRUE;
  606.  
  607.         while(keepgoing)
  608.         {
  609.             signals = Wait(timersignal | idcmpsignal);
  610.             if(signals & timersignal)
  611.             {
  612.                 GetMsg(timerport);
  613.                 addtimerequest(1,0);
  614.                 if(100*cputime/60<100)
  615.                     cputemp=cputime;
  616.                 cputemp2+=100*cputime/60;
  617.                 cpuload=cputemp2/++jakaja;
  618.                 cputime=0;
  619.                 currenttime();
  620.                 updatememorybar();
  621.                 sprintf(temp,"%d perfect numbers.",count);
  622.                 abouttext[6].IText=(UBYTE *)temp;
  623.             }
  624.             if(signals & idcmpsignal)
  625.             {
  626.                 while(msg=(struct IntuiMessage *)GetMsg(window->UserPort))
  627.                 {
  628.                     class=msg->Class;
  629.                     code=msg->Code;
  630.                     qualifier=msg->Qualifier;
  631.                     ReplyMsg((struct Message *) msg);
  632.  
  633.                     switch(class)
  634.                     {
  635.                         case CLOSEWINDOW:
  636.                             keepgoing=FALSE;
  637.                             break;
  638.                         case MOUSEBUTTONS:
  639.                             if(code==MENUDOWN)
  640.                                 AutoRequest(NULL,&abouttext[0],NULL,&proceed,NULL,NULL,272,128);
  641.                     }
  642.                 }
  643.             }
  644.         }
  645.     }
  646.     cleanexit(0);
  647. }
  648.